import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;

public class XMLAnalyzer {
	
	static final int DEBUG = 0;
	
	public static void main(String[] args) throws IOException{
		File curDirectory = new File(".");
		
		
		String Files[] = curDirectory.list();
		
		String summaryFileNm	= "summary.txt";	//요약파일명
		File summaryFile = new File(summaryFileNm);
		FileWriter summaryFileWriter = new FileWriter(summaryFile);
		PrintWriter summaryPrintWriter = new PrintWriter(summaryFileWriter);
		
		for (int target = 0 ; target < Files.length ; target++){
			if (!Files[target].toString().substring(Files[target].toString().length()-3, Files[target].toString().length()).equalsIgnoreCase("xml")) continue;
			
			String srcXMLFileNm = Files[target];						//입력파일명
			String trgTXTFileNm	= srcXMLFileNm.replace(".xml", ".txt");	//출력파일명 ( 입력파일명에서 확장자만 변경 )
			
			summaryPrintWriter.println(srcXMLFileNm);
			
			File srcFile = new File(srcXMLFileNm);
			File trgFile = new File(trgTXTFileNm);
			System.out.println("Analyzing "+srcXMLFileNm + "...");
			
			
			
			try {
				FileReader srcReader = new FileReader(srcFile);
				FileWriter trgWriter = new FileWriter(trgFile);
				
				BufferedReader buffer = new BufferedReader(srcReader);
				PrintWriter writer = new PrintWriter(trgWriter);
							
				char[] cbuf = new char[1];
				
				boolean commentLine = false;
				boolean commentBlock = false;
				boolean isFunctionNm = false;
				
				int cntSlash = 0;
				
				String token = new String();
				String functionNm = new String();
				String currentFunctionNm = new String();
				ArrayList<String> functionList = new ArrayList<String>();
				ArrayList<String> functionListNew = new ArrayList<String>();
				
				functionListNew.clear();
				//파일 읽기 시작. 
				while( buffer.read(cbuf)!= -1){
					
					if (commentLine == true){//한줄 주석중인 경우.
						if (String.valueOf(cbuf).equalsIgnoreCase("\n") || String.valueOf(cbuf).equalsIgnoreCase("\r")) {
							commentLine = false;
							continue;
						}
					}
					else if (commentBlock == true){//블럭 주석중인 경우.
						if (String.valueOf(cbuf).equalsIgnoreCase("/")){
							if (String.valueOf(token).equalsIgnoreCase("*")){
								commentBlock = false;
								continue;
							}							
						}
						token = String.valueOf(cbuf);
						continue;
					}
					else {
						if (cntSlash != 0){
							if (String.valueOf(cbuf).equalsIgnoreCase("/")){
								commentLine = true;	
								continue;
							}
							else if (String.valueOf(cbuf).equalsIgnoreCase("*")){
								commentBlock = true;
								continue;
							}						
							cntSlash = 0;						
						}
						
						//실제 처리부.
						
						if (isFunctionNm){							
							if (String.valueOf(cbuf).equalsIgnoreCase("(")){//함수이름 종료.
								isFunctionNm = false;
								currentFunctionNm = functionNm;
								functionNm = "";
							}
							else {
								functionNm = functionNm.concat(String.valueOf(cbuf));
							}
						}
						else if (String.valueOf(cbuf).equalsIgnoreCase("/")){
							cntSlash++;
							continue;
						}
						
						if (String.valueOf(cbuf).equalsIgnoreCase(" ") || String.valueOf(cbuf).equalsIgnoreCase("\n") || String.valueOf(cbuf).equalsIgnoreCase("\r") || String.valueOf(cbuf).equalsIgnoreCase("\t")){
							token = "";
							
						}
						else {
							token = token.concat(String.valueOf(cbuf));
						}
						if (token.equalsIgnoreCase("function")){
							isFunctionNm = true;
							continue;
						}
						if (token.equalsIgnoreCase("sfn_transaction")){
							functionListNew.add(currentFunctionNm.trim());
							continue;
						}
						if (DEBUG == 1) System.out.print(cbuf);
					}
				}
				
				// 여기까지 함수 추출. (최초 트랜잭션을 가진 함수들.)
				for (String temp : functionListNew){
					if (!String.valueOf(temp).equalsIgnoreCase("fn_callback")) {
						if (!functionList.contains(temp))functionList.add(temp);
					}
				}
				
				
				/*********************************
				 * 최초 트랜잭션을 가진 함수 추출 완료.
				 */
				writer.println("transaction을 가진 함수 목록");
				for (String temp : functionList) writer.println(temp+"()");
				writer.println();
				
				
				//반복!!!!!
				int functionCnt = functionList.size();
				for(int loop = 2 ; loop < 12 ; loop++){
					
					functionListNew.clear();
					
					//파일 다시 열기.
					buffer.close();
					srcReader.close();
					srcReader = new FileReader(srcFile);
					buffer = new BufferedReader(srcReader);
					
					String strReadLine = new String();
					
					//스크립트 이전은 모두 스킵.
					while((strReadLine = buffer.readLine()) != null){
						if (strReadLine.trim().equalsIgnoreCase("</Form>")) break;
					}
					
		
					int depth = 0;
					
					//파일 읽기 시작. 
					while( buffer.read(cbuf)!= -1){
						
						if (commentLine == true){//한줄 주석중인 경우.
							if (String.valueOf(cbuf).equalsIgnoreCase("\n") || String.valueOf(cbuf).equalsIgnoreCase("\r")) {
								commentLine = false;
								continue;
							}
						}
						else if (commentBlock == true){//블럭 주석중인 경우.
							if (String.valueOf(cbuf).equalsIgnoreCase("/")){
								if (String.valueOf(token).equalsIgnoreCase("*")){
									commentBlock = false;
									continue;
								}							
							}
							token = String.valueOf(cbuf);
							continue;
						}
						else {
							if (cntSlash != 0){
								if (String.valueOf(cbuf).equalsIgnoreCase("/")){
									commentLine = true;	
									continue;
								}
								else if (String.valueOf(cbuf).equalsIgnoreCase("*")){
									commentBlock = true;
									continue;
								}						
								cntSlash = 0;						
							}
							
							//실제 처리부.
							
							if (isFunctionNm){
								if (String.valueOf(cbuf).equalsIgnoreCase("(")){//함수이름 종료.
									isFunctionNm = false;
									currentFunctionNm = functionNm;							
									functionNm = "";
								}
								else {
									functionNm = functionNm.concat(String.valueOf(cbuf));
								}
							}
							else if (String.valueOf(cbuf).equalsIgnoreCase("/")){
								cntSlash++;
							}
							else if (String.valueOf(cbuf).equalsIgnoreCase("{")){
								depth++;
							}
							else if (String.valueOf(cbuf).equalsIgnoreCase("}")){
								depth--;
								if (depth == 0){
	
								}
							}
							if (String.valueOf(cbuf).equalsIgnoreCase(" ") || String.valueOf(cbuf).equalsIgnoreCase("\n") || String.valueOf(cbuf).equalsIgnoreCase("\r") || String.valueOf(cbuf).equalsIgnoreCase("\t")){
								token = "";
							}
							else {
								token = token.concat(String.valueOf(cbuf));
							}
							if (token.equalsIgnoreCase("function")){
								isFunctionNm = true;
								continue;
							}
	
							
							for (String temp : functionList){
								temp = temp+"(";
								if (token.equalsIgnoreCase(temp)){
									functionListNew.add(currentFunctionNm.trim());
									continue;
								}
							}
						}
					}
					
					writer.println(loop+"차 함수 목록");
					for (String temp : functionListNew){
						if (!String.valueOf(temp).equalsIgnoreCase("fn_callback")) {
							if (!functionList.contains(temp)){
								functionList.add(temp);
								writer.println(temp+"()");
							}
						}
					}
					//이전과 달라진 것이 없으면 종료.
					if (functionCnt == functionList.size()) break;
					else functionCnt = functionList.size();
					writer.println();
				}
			
				/**
				 * 함수 추출 완료.
				 * 
				 */
	
				
				//파일 다시 열기.
				buffer.close();
				srcReader.close();
				srcReader = new FileReader(srcFile);
				buffer = new BufferedReader(srcReader);
				String strReadLine = new String();
				
				writer.println("\n기능목록");
				while((strReadLine = buffer.readLine()) != null){
					String xmlTokens[] = strReadLine.split(" ");
					String id = new String();
					String event = new String();
					for (int i = 0 ; i < xmlTokens.length ; i++){
						String xmlSmallTokens[] = xmlTokens[i].split("=");					
						if (xmlSmallTokens.length != 2) continue;
						xmlSmallTokens[0] = xmlSmallTokens[0].replace("\"", "");
						xmlSmallTokens[1] = xmlSmallTokens[1].replace("\"", "");
						xmlSmallTokens[0] = xmlSmallTokens[0].replace("<", "");
						xmlSmallTokens[1] = xmlSmallTokens[1].replace("<", "");
						xmlSmallTokens[0] = xmlSmallTokens[0].replace(">", "");
						xmlSmallTokens[1] = xmlSmallTokens[1].replace(">", "");
						for (int j = 0 ; j < xmlSmallTokens.length ; j++){
							if (String.valueOf(xmlSmallTokens[0]).equalsIgnoreCase("id")) id = xmlSmallTokens[1];
							else {
								for (String temp:functionList){
									if (temp.equalsIgnoreCase(xmlSmallTokens[1])) {
										event = xmlSmallTokens[0];
										break;
									}
								}
							}
						}					
					}
					if (event.length() != 0){
						writer.println(id + "\t" + event);
						summaryPrintWriter.println(id + "\t" + event);
					}
				}
				
				buffer.close();
				writer.close();
				trgWriter.close();
				srcReader.close();
			}catch (FileNotFoundException e) {
				e.printStackTrace();
			}
			
			summaryPrintWriter.println();
		}
		summaryPrintWriter.close();
	}
}
